#day2 数据清洗与统计
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler        # 用于数据标准化

def handle_missing(df, col, method='mean'):
    """
    处理缺失值。可选填充方式包括均值、众数、中位数。
    :param df: DataFrame对象
    :param col: 需要填充的列名
    :param method: 填充方式（'mean', 'median', 'mode'）
    :return: 填充后的DataFrame
    """
    if method == 'mean':
        df[col].fillna(df[col].mean(), inplace=True)
    elif method == 'median':
        df[col].fillna(df[col].median(), inplace=True)
    elif method == 'mode':
        df[col].fillna(df[col].mode()[0], inplace=True)
    return df

def remove_duplicates(df, subset=None):
    """
    去除重复值。
    :param df: DataFrame对象
    :param subset: 用于识别重复的列名（可选）
    :return: 去重后的DataFrame
    """
    return df.drop_duplicates(subset=subset)

def remove_outliers_iqr(df, col):
    """
    使用IQR方法处理异常值（只保留正常范围内的数据）。
    :param df: DataFrame对象
    :param col: 需要处理异常值的列名
    :return: 处理后的DataFrame
    """
    Q1 = df[col].quantile(0.25)
    Q3 = df[col].quantile(0.75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    return df[(df[col] >= lower_bound) & (df[col] <= upper_bound)]

def convert_to_category(df, col):
    """
    将指定列转换为分类类型（category）。
    :param df: DataFrame对象
    :param col: 需要转换的列名
    :return: 转换后的DataFrame
    """
    df[col] = df[col].astype('category')
    return df

def one_hot_encode(df, cols):
    """
    对指定的分类列进行独热编码。
    :param df: DataFrame对象
    :param cols: 需要编码的列名列表
    :return: 编码后的DataFrame
    """
    return pd.get_dummies(df, columns=cols)

def standardize_columns(df, cols):
    """
    对指定的数值列进行标准化（均值为0，方差为1）。
    :param df: DataFrame对象
    :param cols: 需要标准化的列名列表
    :return: 标准化后的DataFrame
    """
    scaler = StandardScaler()
    df[cols] = scaler.fit_transform(df[cols])
    return df

def group_and_aggregate(df, group_col, agg_dict):
    """
    按指定列分组并聚合（如平均值）。
    :param df: DataFrame对象
    :param group_col: 分组列名
    :param agg_dict: 聚合方式字典，例如 {'A':'mean','B':'mean'}
    :return: 分组聚合后的DataFrame
    """
    return df.groupby(group_col).agg(agg_dict)


# 主流程入口
if __name__ == "__main__":
    # 构建原始数据，包含缺失值、重复值、异常值
    raw_data = pd.DataFrame({
        'A': [1, 2, np.nan, 4, 1, 2, 3, 4, 5, 100],
        'B': [5, 6, 7, 8, 5, 6, 7, 8, 9, 10],
        'C': ['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'e', 'f'],
        'D': [1.1, 2.2, 3.3, 4.4, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6]
    })
    print("原始数据：\n", raw_data)
    
    # 1. 处理缺失值：对'A'列使用均值填充
    cleaned_data = handle_missing(raw_data.copy(), 'A', method='mean')
    print("\n处理缺失值后的数据：\n", cleaned_data)

    # 2. 去除重复值
    cleaned_data = remove_duplicates(cleaned_data)
    print("\n去除重复值后的数据：\n", cleaned_data)

    # 3. 处理异常值：对'A'列使用IQR方法
    cleaned_data = remove_outliers_iqr(cleaned_data, 'A')
    print("\n处理异常值后的数据：\n", cleaned_data)

    # 4. 数据类型转换：将'C'列转换为分类类型
    cleaned_data = convert_to_category(cleaned_data, 'C')
    print("\n数据类型转换后的数据：\n", cleaned_data.dtypes)

    # 5. 查看清洗后数据的统计信息
    print("\n清洗后数据的基本统计信息：\n", cleaned_data.describe(include='all'))

    # 6. 对分类数据做独热编码
    encoded_data = one_hot_encode(cleaned_data, ['C'])
    print("\n独热编码后的数据：\n", encoded_data)

    # 7. 对数值列做标准化处理
    standardized_data = standardize_columns(cleaned_data.copy(), ['A', 'B', 'D'])
    print("\n标准化后的数据：\n", standardized_data)

    # 8. 数据分组与聚合：按'C'分组并计算平均值
    agg_result = group_and_aggregate(cleaned_data, 'C', {'A':'mean','B':'mean','D':'mean'})
    print("\n按列'C'分组的平均值：\n", agg_result)


